package it.arteinsieme.main;

import it.arteinsieme.model.ArteInsieme2010;
import it.arteinsieme.repository.ArteInsieme2010Repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;

import org.giavacms.exhibition.enums.ParticipationType;
import org.giavacms.exhibition.model.Artist;
import org.giavacms.exhibition.model.Discipline;
import org.giavacms.exhibition.model.Exhibition;
import org.giavacms.exhibition.model.Participant;
import org.giavacms.exhibition.repository.ArtistRepository;
import org.giavacms.exhibition.repository.DisciplineRepository;
import org.giavacms.exhibition.repository.ExhibitionRepository;


public class Importazione2010
{

   private static final String UNIT_NAME = "ArteInsiemeEclipse";

   private static boolean commit = true;

   private static EntityManager em;
   private static EntityTransaction etx;

   private static ExhibitionRepository exhibitionRepository;
   private static ArtistRepository artistRepository;
   private static DisciplineRepository disciplineRepository;
   private static ArteInsieme2010Repository arteInsieme2010Repository;

   public static void main(String[] args)
   {

      // inizializzo la base di dati gestita da hibernate
      Map<String, String> configOverrides = new HashMap<String, String>();
      // configOverrides.put("hibernate.show_sql","true");
      // configOverrides.put("hibernate.hbm2ddl.auto","create-drop");
      EntityManagerFactory entityManagerFactory = Persistence
               .createEntityManagerFactory(UNIT_NAME, configOverrides);
      em = entityManagerFactory.createEntityManager();
      etx = em.getTransaction();
      etx.begin();

      exhibitionRepository = new ExhibitionRepository();
      exhibitionRepository.setEm(em);
      artistRepository = new ArtistRepository();
      artistRepository.setEm(em);
      arteInsieme2010Repository = new ArteInsieme2010Repository();
      arteInsieme2010Repository.setEm(em);
      disciplineRepository = new DisciplineRepository();
      disciplineRepository.setEm(em);

      Exhibition exhibition = null;

      System.out.println("Selezione evento:");
      for (Exhibition e : exhibitionRepository.getAllList())
      {
         System.out.println(e.getName());
         if (e.getName().contains("2010"))
         {
            exhibition = e;
            break;
         }
      }
      if (exhibition == null)
      {
         System.err.println("Evento 2010 non trovato.");
         System.exit(-1);
      }
      else
      {
         System.out.println("Evento selezionato: " + exhibition.getName());
      }

      System.out.println("Conteggio voci 2010:");
      List<ArteInsieme2010> voci = arteInsieme2010Repository.getAllList();
      int arteInsieme2010size = voci.size();
      if (arteInsieme2010size == 0)
      {
         System.err.println("Voci 2010 non trovate.");
         System.exit(-1);
      }
      else
      {
         System.out.println(arteInsieme2010size + " voci.");
      }

      try
      {
         for (ArteInsieme2010 voce : voci)
         {
            if ((voce.getNome() == null || voce.getNome().trim().length() == 0)
                     && (voce.getCognome() == null || voce.getCognome()
                              .trim().length() == 0))
            {
               throw new RuntimeException(
                        "Generalita' non presenti per la voce #"
                                 + voce.getId());
            }
            if ((voce.getNome() != null && voce.getNome().contains("'"))
                     || (voce.getCognome() != null && voce.getCognome()
                              .contains("'")))
            {
               throw new RuntimeException(
                        "Generalita' con lettere accentate per la voce #"
                                 + voce.getId());
            }
            Artist artist = trovaArtista(voce.getNome(), voce.getCognome(),
                     voce.getNomedarte());
            if (voce.getDisciplina() == null
                     || voce.getDisciplina().trim().length() == 0)
            {
               throw new RuntimeException(
                        "Disciplina non presente per la voce #"
                                 + voce.getId());
            }
            Discipline discipline = trovaDisciplina(voce.getDisciplina());
            Participant participant = creaParticipante(voce, artist,
                     discipline, exhibition);
            System.out.println("Creato partecipante #"
                     + participant.getId()
                     + " - "
                     + participant.getOeuvreTitle()
                     + (participant.getExternalImage() == null ? ""
                              : (" - " + participant.getExternalImage())));
         }

         if (commit)
         {
            etx.commit();
         }
         else
         {
            etx.rollback();
         }
      }
      catch (Exception e)
      {
         e.printStackTrace();
         etx.rollback();
      }

   }

   private static Artist trovaArtista(String nome, String cognome,
            String nomedarte)
   {
      String separator = " where ";
      String q = "select a from " + Artist.class.getSimpleName() + " a ";
      if (nome != null)
      {
         q += separator + " upper(a.name) = '" + nome.trim().toUpperCase()
                  + "'";
         separator = " and ";
      }
      if (cognome != null)
      {
         q += separator + " upper(a.surname) = '"
                  + cognome.trim().toUpperCase() + "'";
         separator = " and ";
      }
      @SuppressWarnings("unchecked")
      List<Artist> la = em.createQuery(q).getResultList();
      if (la != null)
      {
         if (la.size() > 1)
         {
            throw new RuntimeException("Ambiguita' sull'artista: " + nome
                     + " " + cognome + " " + nomedarte);
         }
         if (la.size() == 1)
         {
            Artist a = la.get(0);
            if (a.getArtistName() == null
                     || a.getArtistName().trim().length() == 0)
            {
               a.setArtistName(nomedarte);
               em.merge(a);
            }
            return a;
         }
      }
      Artist a = new Artist();
      if (nome != null)
      {
         a.setName(nome.trim());
      }
      if (cognome != null)
      {
         a.setSurname(cognome.trim());
      }
      a.setArtistName(nomedarte == null ? null : nomedarte.trim());
      a = artistRepository.persist(a);
      return a;
   }

   private static Discipline trovaDisciplina(String nome)
   {
      if ("POESIA".equals(nome.toUpperCase()))
      {
         nome = "Poesia/Narrativa";
      }
      String separator = " where ";
      String q = "select a from " + Discipline.class.getSimpleName() + " a ";
      if (nome != null)
      {
         q += separator + " upper(a.name) = '" + nome.trim().toUpperCase()
                  + "'";
         separator = " and ";
      }
      @SuppressWarnings("unchecked")
      List<Discipline> la = em.createQuery(q).getResultList();
      if (la != null)
      {
         if (la.size() > 1)
         {
            throw new RuntimeException("Ambiguita' sulla disciplina: "
                     + nome);
         }
         if (la.size() == 1)
         {
            return la.get(0);
         }
      }
      System.out.println("Discplina non trovata: " + nome);
      Discipline a = new Discipline();
      if (nome != null)
      {
         a.setName(nome.trim());
      }
      em.persist(a);
      return a;
   }

   private static Participant creaParticipante(ArteInsieme2010 voce,
            Artist artist, Discipline discipline, Exhibition exhibition)
   {
      Participant p = new Participant();
      p.setSubject(artist);
      p.setDescription(voce.getBiografia());
      p.setDate(voce.getData());
      p.setDimensions(voce.getDimensioni());
      p.setDiscipline(discipline);
      p.setEmail(voce.getEmail());
      p.setExhibition(exhibition);
      //
      p.setExternalImage(recuperaFoto(voce.getId()));
      p.setFacebookAccount(null);
      p.setImage(null);
      p.setInstagramAccount(null);
      p.setMaterial(voce.getMateriale());
      p.setOeuvreTitle(voce.getNomeopera());
      // per il 2010 tutte fisiche
      p.setParticipationType(ParticipationType.PHISICAL);
      p.setPhone(voce.getTelefono());
      p.setSummary(voce.getDescrizione_sintetica());
      p.setTwitterAccount(null);
      p.setWebSite(null);
      em.persist(p);
      return p;
   }

   private static String recuperaFoto(Long idVoce)
   {
      String q = "select f.foto from foto f where f.id_art2010 = " + idVoce;
      @SuppressWarnings("unchecked")
      List<String> lf = em.createNativeQuery(q).getResultList();
      if (lf == null || lf.size() == 0)
      {
         return null;
      }
      else
      {
         return lf.get(0);
      }
   }

}
